<?php
namespace My\Controller;

use Utuo\BackgroundController;

class DriverSnapController extends BackgroundController {
	
	private $termId = null;
	
	private $termConfig = null;
	
	private $rank = null;
	
	private $rankSnap = null;
	
	private $status = array(
		'0' => '已禁用',
		'1' => '正常',
	);
	
	public function _initialize() {
		$this->termId = I('term_id', 0, "intval") or $this->error('请先选择期次');
		$this->termConfig = $this->getTermConfig();
		$this->setControllerTitle("历史发布排行榜");
		$this->setActionTitle(array(
						'index' => '历史发布',
						'snapRecord' => '历史发布排名记录',
						'viewVote' => '距上次发布票数增长情况',
				), '', 'term_id='.$this->termId);
		$this->setActionNav("index");
		$this->rank = new \Utuo\Rank( array('namespace' => $this->termConfig['rank_name']) );
		$this->rankSnap = new \Utuo\Rank( array('namespace' => $this->termConfig['rank_snap_name']) );
		$this->assign("termId", $this->termId);
	}
	
	public function getLists($is_deleted = 0) {
		$status = I("status", -1, 'intval');
		$page = I('p', 0, 'intval');
		$condition = array(
				'a.cid' => $this->aid,
				'a.term_id' => $this->termId,
		);
		$m = M("DriverSnap a")->where( $condition )->field("a.*");
		$n = clone $m;
		$driverSnapCount = $n->count();
		$driverSnapLists = $m->page($page)->limit($this->pageSize)->order("a.id desc")->select();
		$publishTimeRange = $this->getPublishTimeRange();
		$process = session( "process_{$this->termId}" );
		$this->showPage($driverSnapCount, $this->pageSize);
		$this->assign("driverSnapLists", $driverSnapLists);
		$this->assign("timeRange", $publishTimeRange);
		if ( $process ) {
			$this->assign("progress", 1);
			//session( "process_{$this->termId}", null );
			//dump($process);
		} 
		$this->display();
	}
	
	/**
	 * 发布排行
	 */
	public function publishAction() {
		$limit = 100;
		$beginTime = I('startDate', 0, 'strtotime');
		$endTime = I('endDate', 0, 'strtotime');
		$condition = array('a.cid'=>$this->aid, 
						   'a.term_id'=>$this->termId,
						   'b.is_deleted' => 0,);
		// 任务初始处理
		$process = session( "process_{$this->termId}" );
		$Completed = false;
		if ( $process ) {
			$snapId = $process->snap['id'];
			$beginTime = $process->snap['begin_time'];
			$endTime = $process->snap['end_time'];
			$condition['b.create_time'] = array(array('egt', $beginTime), array('elt', $endTime), 'and');
			$process->steps['step1']['status']==0 and $condition['a.id'] = array('gt', $process->steps['step1']['lastDriverId']); // 从断点处查找
		} else {
			$Completed = true;
			
			// 添加任务记录历史
			$snapId = M("DriverSnap")->add(array(
					'cid' => $this->aid,
					'term_id' => $this->termId,
					'count' => -1,
					'end_time' => $endTime,
					'create_time' => time(),
			));
			
			// 查询时间范围内增加的票数(计算任务一数据量)
			$condition['b.create_time'] = array(array('egt', $beginTime), array('elt', $endTime), 'and');
			$m = M('Driver a')->join("__DRIVER_VOTE__ b on a.id=b.driver_id")
									->where($condition)
									->field('a.id,count(b.driver_id) as inc')
									->order("a.id asc")
									->group("b.driver_id");
			$total = M()->table($m->select(false)." a")->count();
			
			// 初始进度
			$process = (object)array('snap' => array('id' => $snapId, 'begin_time' => $beginTime, 'end_time' => $endTime), 'steps' => array( 'step1' => array('status'=>0, 'lastDriverId'=>0, 'total' => $total, 'completed' => 0 ), 'step2' => array('status'=>0, 'total' => 1, 'completed' => 0), )); // 初始进度
			session( "process_{$this->termId}", $process );
		}
		
		// 查询时间范围内增加的票数(计算任务一数据)
		$driverList = M('Driver a')->join("__DRIVER_VOTE__ b on a.id=b.driver_id")
								->where($condition)
								->field('a.id,count(b.driver_id) as inc')
								->order("a.id asc")
								->group("b.driver_id")
								->limit($limit)
								->select();
		// 更新历史排行数据(任务一)
		if ( $process->steps['step1']['status'] == 0 ) {
			foreach ( $driverList as $k => $v ) {
				$this->rankSnap->increase($v['id'], $v['inc']);
				$process->steps['step1']['lastDriverId'] = $v['id'];
				$process->steps['step1']['completed'] = $process->steps['step1']['completed'] + 1;
			}
			
			if ( $process->steps['step1']['completed'] >= $process->steps['step1']['total'] ) {
				$process->steps['step1']['status'] = 1;
			} else {
				$this->ajaxError("中断中...".'-'.$process->steps['step1']['completed'].'-'.$process->steps['step1']['total'] );
			}
		}
		
		// top500
		if ( $process->steps['step2']['status'] == 0 ) {
			// 查询本次最大增长Top500
			$driverListTop = M('Driver a')->join("__DRIVER_VOTE__ b on a.id=b.driver_id")
										 ->where(array('a.cid'=>$this->aid, 
									   				 'a.term_id'=>$this->termId,
													 'b.create_time' => array(array('egt', $beginTime), array('elt', $endTime), 'and'),
										 			 'b.is_deleted' => 0,
										  		))
										->field('a.id,count(b.driver_id) as inc')
										//->order("count(b.driver_id) desc")
										->group("b.driver_id")
										->limit(500)
										->select();
			$driverListTopKV = array();
			foreach ( $driverListTop as $k => $v) {
				$driverListTopKV[$v['id']] = $v['inc'];
			}
			// 发布后Top500
			$topList = $this->rankSnap->getList(true, 0, 499);
			$top = array();
			foreach ( $topList as $v ) {
				$top[] = array(
					'cid' => $this->aid,
					'term_id' => $this->termId,
					'driver_id' => key($v),
					'snap_id' => $snapId,
					'rank' => $this->rankSnap->getRank(key($v)),
					'vote' => current($v),
					'inc' => $driverListTopKV[key($v)]*1,
				);
			}
			if ( false === M("DriverSnapRecord")->addAll( $top ) ) {
				$this->ajaxError("保存TOP500失败");
			}
			$process->steps['step2']['completed'] = $process->steps['step2']['total'];
			$process->steps['step2']['status'] = 1;
		}
		session( "process_{$this->termId}", null );
		$this->ajaxSuccess("发布完成");
	}
	
	// 获得任务进度
	public function getProgressAction() {
		$p = 0;
		$total = 0;
		$completed = 0;
		// 任务初始处理
		$process = session( "process_{$this->termId}" );
		if ( $process ) {
			foreach ( $process->steps as $k => $v ) {
				$total+=$v['total'];
				$completed+=$v['completed'];
			}
			if ( !$total and !$completed ) {
				$p = 100;
			} else {
				$p = floor($completed / $total * 100) ;
			}
		} else {
			$p = 100;
		}
		$this->ajaxSuccess("$completed/$total=".((($completed / $total))), array('progress' => $p, 'total' => $total, 'completed' => $completed));
	}
	
	public function snapRecordAction() {
		$id = I('id', 0, 'intval');
		$pageSize = $this->getPageSize();
		$page = $this->getPage();
		$driverSnap = M("DriverSnap")->where('id=%d', $id)->find();
		$m = M("DriverSnapRecord a")->where(array('a.snap_id'=>$id));
		$n = clone $m;
		$totalRows = $n->count();
		$list = $m->join('__DRIVER__ b on a.driver_id=b.id', 'LEFT')->page($page)->limit($pageSize)->field("a.*,b.name,b.service_no,b.tel")->select();
		$this->showPage($totalRows, $pageSize);
		$this->assign("topList", $list);
		$this->assign("driverSnap", $driverSnap);
		$this->display();
	}
	
	/**
	 * 距上次发布票数增长情况
	 */
	public function viewVoteAction() {
		$p = $this->getPage();
		$pageSize = $this->getPageSize();
		$beginTime = I('startDate', 0, 'strtotime');
		$endTime = I('endDate', 0, 'strtotime');
		$m = M('Driver a')->join("__DRIVER_VOTE__ b on a.id=b.driver_id")
						->where(array('a.cid'=>$this->aid,
								'a.term_id'=>$this->termId,
								'b.create_time' => array(array('egt', $beginTime), array('elt', $endTime), 'and'),
								'b.is_deleted' => 0,
						))
						->field('a.id,a.name,a.tel,a.service_no,count(b.driver_id) as inc')
						->order("count(b.driver_id) desc")
						->group("b.driver_id");
		$o = M()->table($m->select(false)." a");
		$n = clone $o;
		$totalRows = $o->count();
		$driverLists = $n->page($p)->limit($pageSize)->select();
		$this->assign("driverLists", $driverLists);
		$this->showPage($totalRows, $pageSize);
		$this->display();
	}
	
	/**
	 * 获得发布日期范围
	 * @return multitype:number
	 */
	private function getPublishTimeRange() {
		$driverSnap = M("DriverSnap")->where(array('term_id'=>$this->termId, 'cid'=>$this->aid))->order('end_time desc')->find(); // 最后统计
		$begin_time = $this->termConfig['begin_time']; // 默认从活动开始时间统计
		$end_time = time(); // 统计截止至现在
		if ( $driverSnap ) {
			$begin_time = $driverSnap['end_time']+1;
		}
		return array($begin_time, $end_time);
	}
	
	/**
	 * 获得期次配置
	 * @return mixed
	 */
	private function getTermConfig() {
		$driverTerm = M('DriverTerm')->where('cid=%d', $this->aid)->find( $this->termId );
		return unserialize( $driverTerm['config'] );
	}
	
}